---
title: 'Simple LPEG for Lisp (vis editor)'
date: 2019-06-01
---

Getting back into clojure recently has made me realize how nice lisp is in that is has almost no "syntax". Everything on a page of clojure code is basically just function calls; so really there's just two kinds of *things*: function names and arguments. Syntax highlighting for lisp as such I think should reflect that simplicity.

So I decided I'd write my own (minimal) syntax highlighter for my preferred editor [vis](https://github.com/martanne/vis) in LPEG. What I wanted in my syntax highlighter for lisp to highlight was simple: (1) comments, (2) function names (e.g. the first parameter in lists), and (3) the first function argument (e.g. all function second argument in case of defn etc.)

Here's the final lpeg highlighter code (e.g. add to `~/.config/vis/themes/mlisp.clj` and then `set syntax=mlisp`):

```lua
local l = require('lexer')
local token, word_match = l.token, l.word_match
local P, R, S, C = lpeg.P, lpeg.R, lpeg.S, lpeg.C
local M = {_NAME = 'lisp'}

local line_comment = ';' * l.nonnewline^0
local block_comment = '#_(' * (l.any - ')')^0 * P(')')
local firstargchars = l.any - ' ' - ')' - '(';
local secondargchars = l.any - ' ' - ')' - '(' - '[' - ']' - '"';

local fn_call_arg_one = token(
  l.KEYWORD, lpeg.B('(') * (firstargchars)^1
);
local fn_call_arg_two  = token(
  l.TYPE, (' ' * secondargchars^1)^-1
);
local comment = token(
  l.COMMENT, line_comment + block_comment
);

M._rules = {
  {'fn_call', fn_call_arg_one * fn_call_arg_two },
  {'comment', comment}
};

return M;
```
